package com.example.wlzz.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.wlzz.api.ConfigAPI;
import com.example.wlzz.constant.RedisConstant;
import com.example.wlzz.crawler.LoginPage;
import com.example.wlzz.dto.CrawlerGradeDTO;
import com.example.wlzz.dto.CrawlerResultDTO;
import com.example.wlzz.dto.MajorKlass;
import com.example.wlzz.entity.Major;
import com.example.wlzz.entity.mongoEntity.KlassForUser;
import com.example.wlzz.enums.ResultEnum;
import com.example.wlzz.form.CrawlerForm;
import com.example.wlzz.repository.DepartmentWebRepository;
import com.example.wlzz.repository.MajorRepository;
import com.example.wlzz.repository.mongoRepository.KlassRepository;
import com.example.wlzz.service.UserInfoService;
import com.example.wlzz.utils.CodeRequestUtil;
import com.example.wlzz.utils.ResultVOUtil;
import com.example.wlzz.vo.CodeVO;
import com.example.wlzz.vo.ResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.*;

@RestController
@RequestMapping("/wlzzCrawler")
@Slf4j
@Api(tags = "临沂大学爬虫模块")
public class CrawlerController {
    @Autowired
    private DepartmentWebRepository departmentWebRepository; //直接注入Dao了。
    @Autowired
    private ConfigAPI configAPI;
    @Autowired
    private MajorRepository majorRepository;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private KlassRepository klassRepository;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @PostMapping("/first")
    @ApiOperation("第一步：进入这里获取登陆的cookie和验证码")
    public ResultVO first(@ApiParam("token") @RequestParam("token") String token){
            try {
               LoginPage loginPage = new LoginPage();
               Map<String,String> cookies = loginPage.getCookie("http://jwxt.lyu.edu.cn/jxd/"); //去获取cookie
               CodeVO codeVO =  CodeRequestUtil.codeRequest("http://jwxt.lyu.edu.cn/jxd/verifycode.servlet",cookies,configAPI.getName());
               return ResultVOUtil.success(codeVO);
            }catch (Exception e){
                e.printStackTrace();
                return ResultVOUtil.error(ResultEnum.GET_CLASS_ERROR.getCode(),ResultEnum.GET_CLASS_ERROR.getMessage());
            }
    }
    @PostMapping("/second")
    @ApiOperation("第二步：将【第一步】拿到的cookie放进对应的输入框里(登陆成功则返回对应的cookie)【提示：登陆成功将会更新个人信息的学号和密码】")
    public ResultVO second(@Valid CrawlerForm crawlerForm , BindingResult bindingResult,@ApiParam("token") @RequestParam("token") String token)throws Exception{
        if(bindingResult.hasErrors()) {
            return ResultVOUtil.error(ResultEnum.LOGIN_SCHOOL_ERROR.getCode(),ResultEnum.LOGIN_SCHOOL_ERROR.getMessage());
        }
        LoginPage loginPage = new LoginPage();
        Map<String,String> map = new HashMap<>();
        String[] array = crawlerForm.getCookie().split("=");
        map.put(array[0],array[1]);
        System.out.println(map);
        System.out.println(crawlerForm);
        ResultVO resultVO = loginPage.login(crawlerForm.getSno(),crawlerForm.getPasswd(),crawlerForm.getCode(),map);
        if(resultVO.getCode()==0){  //登陆成功的话就存储一下学号学号
            userInfoService.alterSnoAndSnoPassword(crawlerForm.getSno(),crawlerForm.getPasswd(),token);//更改用户的学号和密码
        }
        return resultVO;
    }
    @PostMapping("/getDateClass")
    @ApiOperation("根据日期获取相应的学期理论课程表,不传日期的参数则默认得到当前学期的课程表")
    public ResultVO getDateClass(@ApiParam("token") @RequestParam("token") String token,
                                 @RequestParam("cookie") String cookie,
                                 @ApiParam("日期-例子(不传默认当前学期):<br>2017-2018-2<br>2017-2018-1<br>2018-2019-1<br>.......") @RequestParam(value = "xnxq01id",defaultValue = "default") String xnxq01id)throws Exception{
        LoginPage loginPage = new LoginPage();
        Map<String,String> map = new HashMap<>();
        String[] array = cookie.split("=");
        map.put(array[0],array[1]);
        //获得当前学期
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        String currXueqi = (year - 1) + "-" + year+"-2";
        if (month > 7 || month < 2) {   //日期
            currXueqi = year + "-" + (year + 1)+"-1";
        }
        ResultVO resultVO;
        System.out.println(currXueqi);
        if("default".equals(xnxq01id)|currXueqi.equals(xnxq01id)){  //日期等于当前学期
            System.out.println("查询当前学期");
            resultVO = loginPage.getKlassCard(map,currXueqi);
            if(resultVO.getCode()==0){
//                KlassForUser klassForUser = new KlassForUser();
//                //去redis查询
//                String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
//                klassForUser.set_id(tokenValue);
//                klassForUser.setKlassContent(resultVO.getData());
//                klassRepository.save(klassForUser);
            }
        }else{   //查询其他日期
            System.out.println("查询其他学期");
            resultVO = loginPage.getKlassCard(map,xnxq01id);
        }
        return resultVO ;
    }
    @PostMapping("/getMajorClass")
    @ApiOperation("根据行政班级查询课程表")
    public ResultVO getMajorClass(@ApiParam("token") @RequestParam("token") String token,
                                  @RequestParam("cookie") String cookie,
                                  @ApiParam("日期-例子:<br>2017-2018-2<br>2017-2018-1<br>2018-2019-1") @RequestParam(value = "xnxqh",defaultValue = "") String xnxqh,
                                  @ApiParam("上课院系-->可从院系接口获取院系，这里填的是id") @RequestParam(value = "skyx",defaultValue = "") String skyx,
                                  @ApiParam("上课专业") @RequestParam(value = "skzy",defaultValue = "") String skzy,
                                  @ApiParam("上课年级-->年级，如2016，2017，2018") @RequestParam(value = "sknj",defaultValue = "") String sknj
                                 ){
//        @ApiParam("节次起点") @RequestParam(value = "jc1",defaultValue = "") String jc1,
//        @ApiParam("节次结束") @RequestParam(value = "jc2",defaultValue = "") String jc2
        LoginPage loginPage = new LoginPage();
        Map<String,String> cookies = new HashMap<>();
        String[] array = cookie.split("=");
        cookies.put(array[0],array[1]);
        Map<String,String> datas = new HashMap<>();
        datas.put("xnxqh",xnxqh);
        datas.put("skyx",skyx);
        datas.put("sknj",sknj);
        datas.put("skzy",skzy);
        datas.put("zc1","");
        datas.put("zc2","");
//        datas.put("jc1",jc1);
//        datas.put("jc2",jc2);
        try{
            return ResultVOUtil.success(loginPage.getMajorKlass(cookies,datas));
        }catch (Exception e){
            e.printStackTrace();
            return ResultVOUtil.error(ResultEnum.GET_CLASS_ERROR.getCode(),ResultEnum.GET_CLASS_ERROR.getMessage());
        }
    }
    @PostMapping("/getDepartment")
    @ApiOperation("获得临沂大学的院系")
    public ResultVO getDepartment(@ApiParam("token") @RequestParam("token") String token){
        return ResultVOUtil.success(departmentWebRepository.findBySchoolId("1"));
    }
    @PostMapping("/getLocalDepartmentForMajor")
    @ApiOperation("根据院系选择专业(该模块是从本地服务器获取数据)")
    @ApiIgnore
    public ResultVO getLocalDepartmentForMajor(@ApiParam("token") @RequestParam("token") String token,
                                               @ApiParam("上课院系(标识)") @RequestParam(value = "skyx",defaultValue = "") String skyx){
        List<Major>  majorList = majorRepository.findByDepartmentId(skyx);
        return ResultVOUtil.success(majorList);
    }
    @PostMapping("/getDepartmentForMajor")
    @ApiOperation("根据院系选择专业(该模块是从临沂大学即时获取的数据)")
    public ResultVO getDepartmentForMajor(@ApiParam("token") @RequestParam("token") String token,
                                          @RequestParam("cookie") String cookie,
                                           @ApiParam("上课院系") @RequestParam(value = "skyx") String skyx,
                                           @ApiParam("上课年级") @RequestParam(value = "sknj") String sknj){

        StringBuilder stringBuilder = new StringBuilder("http://jwxt.lyu.edu.cn/jxd/kbcx/getZyByAjax?&");
        stringBuilder.append("skyx=");
        stringBuilder.append(skyx);
        stringBuilder.append("&sknj=");
        stringBuilder.append(sknj);
        String[] array = cookie.split("=");
        Map<String,String> cookies = new HashMap<String,String>();
        cookies.put(array[0],array[1]);
        Connection con = Jsoup.connect(stringBuilder.toString());
        con.header("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");// 配置模拟浏览器
        Connection.Response rs ;
        try {
            rs = con.ignoreContentType(true).method(Connection.Method.GET).cookies(cookies).execute();// 获取响应
        }catch(Exception e){
            e.printStackTrace();
            return ResultVOUtil.error(ResultEnum.LOGIN_SCHOOL_ERROR.getCode(),ResultEnum.LOGIN_SCHOOL_ERROR.getMessage());
        }
        String str = rs.body();
        JSONArray jsonArray = JSON.parseArray(str);
        List<MajorKlass> majorKlassList = new ArrayList<>();
        for (Object o : jsonArray) {
            net.sf.json.JSONObject jsonObject =  net.sf.json.JSONObject.fromObject(o);
            MajorKlass majorKlass = new MajorKlass();
            majorKlass.setDm(jsonObject.getString("dm"));
            majorKlass.setDmmc(jsonObject.getString("dmmc"));
            majorKlassList.add(majorKlass);
        }
        return ResultVOUtil.success(majorKlassList);
    }

    @PostMapping("/getGrade")
    @ApiOperation("根据学期获取成绩")
    public ResultVO getGrade(@ApiParam("token") @RequestParam("token") String token,
                                                 @ApiParam("日期-例子:<br>2017-2018-2<br>2017-2018-1<br>2018-2019-1") @RequestParam(value = "xnxqh",defaultValue = "") String xnxqh,
                                                @RequestParam("cookie") String cookie
                                               ) {
        String[] array = cookie.split("=");
        Map<String,String> cookies = new HashMap<String,String>();
        cookies.put(array[0],array[1]);
        Connection con = Jsoup.connect("http://jwxt.lyu.edu.cn/jxd/kscj/cjcx_list");
        con.header("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");// 配置模拟浏览器
        Map<String,String> datas = new HashMap<>();
        datas.put("kksj",xnxqh);
        datas.put("kcxz","");
        datas.put("kcmc","");
        datas.put("xsfs","all");
        Connection.Response rs ;
        try {
            rs = con.ignoreContentType(true)
                    .method(Connection.Method.POST)
                    .ignoreHttpErrors(true)
                    .data(datas)
                    .cookies(cookies)
                    .execute();// 获取响应
            Document document =  rs.parse();
            Element element = document.getElementById("dataList");
            Elements trElements = element.getElementsByTag("tr");
            List<CrawlerGradeDTO> crawlerGradeDTOs = new ArrayList<>();
            CrawlerResultDTO crawlerResultDTO = new CrawlerResultDTO();
            for(int i = 1; i<trElements.size();i++) {
                Elements  tdElements = trElements.get(i).getElementsByTag("td");
                CrawlerGradeDTO crawlerGradeDTO = new CrawlerGradeDTO();
                crawlerGradeDTO.setKlassName(tdElements.get(3).text());
                crawlerGradeDTO.setKlassType(tdElements.get(8).text()+"-"+tdElements.get(9).text());
                crawlerGradeDTO.setGrade(tdElements.get(4).text());
                crawlerGradeDTO.setCredit(tdElements.get(5).text());
                crawlerGradeDTOs.add(crawlerGradeDTO);
            }
            Elements spanElements = document.getElementsByTag("span");
            crawlerResultDTO.setG_Credit(spanElements.get(4).text());
            crawlerResultDTO.setM_Credit(spanElements.get(5).text());
            crawlerResultDTO.setCrList(crawlerGradeDTOs);
           return ResultVOUtil.success(crawlerResultDTO);
        }catch(Exception e){
            e.printStackTrace();
            return ResultVOUtil.error(ResultEnum.LOGIN_SCHOOL_ERROR.getCode(),ResultEnum.LOGIN_SCHOOL_ERROR.getMessage());
        }
    }
}
